/**
 * @projectName practise
 * @package com.wzl.base
 * @className com.wzl.base.StudyDemo04Java8
 * @copyright wzl.
 */
package com.wzl.base;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;

import com.wzl.base.domain.Student;

/**
 * StudyDemo04Java8
 * @description Java8新特性学习
 * @author weiZhiLin
 * @date 2020/12/15 14:36
 * @version 1.0
 */
public class StudyDemo04Java8 {
    public static void main(String[] args) {
        // Stream 参考资料 -》 https://www.runoob.com/java/java8-streams.html
//        testStream01();
//        testStream02();
//        testStream03();
//        testStream04();
//        testOptional01();
//        testOptional02();
//        testStream05();
    }

    // list 转 map
    private static void testStream05() {
        List<String> strings = new ArrayList<>();
        strings.add("abc");
        strings.add("e");
        strings.add("d");
        strings.add("e");
        /**
         * List -> Map
         * 需要注意的是：
         * toMap 如果集合对象有重复的key，会报错Duplicate key ....
         *  apple1,apple12的id都为1。
         *  可以用 (k1,k2)->k1 来设置，如果有重复的key,则保留key1,舍弃key2
         */
        Map<String, String> collect = strings.stream().collect(Collectors.toMap(String::toString, v -> v, (k1, k2) -> k2));
        System.out.println("collect = " + collect);
        // map -> list
        // allkey
        List<String> collect1 = collect.keySet().stream().filter(s -> !s.equals("e")).collect(Collectors.toList());
        collect1.forEach(System.out::println);
        // allvalues
        collect.values().stream().collect(Collectors.toList());
        // 也可以
        ArrayList<String> strings1 = new ArrayList<>(collect.values());
    }

    // optional 一些空值判断
    private static void testOptional02() {
        Optional<String> character = Optional.ofNullable(" ");
        System.out.println(character.isPresent()); // true
        boolean notBlank = StringUtils.isNotEmpty(character.get()); // true
        boolean notBlank2 = StringUtils.isNotBlank(character.get()); // false
        System.out.println(notBlank);
        System.out.println(notBlank2);
    }

    // optional 类学习， optional 可以避免 String isocode = user.getAddress().getCountry().getIsocode().toUpperCase(); 空指针异常
    private static void testOptional01() {
        Student zs = new Student(11, null);
        // name 为空，所以返回 ”空的“
        String s = Optional.ofNullable(zs).map(Student::getName).orElse("空的");
        Student zs2 = null;
        // zs2 为空，所以会报错，若果是 ofNullable 则不会
        String s2 = Optional.of(zs2).map(Student::getName).orElse("空的");
        System.out.println(s);
        System.out.println(s2);
    }

    // Collectors 类实现了很多归约操作，例如将流转换成集合和聚合元素。Collectors 可用于返回列表或字符串：
    private static void testStream04() {
        List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl");
        List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());

        System.out.println("筛选列表: " + filtered);
        String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
        System.out.println("合并字符串: " + mergedString);
    }

    // map 方法用于映射每个元素到对应的结果，以下代码片段使用 map 输出了元素对应的平方数：
    private static void testStream03() {
        List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
        // 获取对应的平方数
        List<Integer> squaresList = numbers.stream().map(i -> i * i).distinct().collect(Collectors.toList());
        squaresList.forEach(System.out::println);
    }

    // 生成随机数
    private static void testStream02() {
        Random random = new Random();
        // 10个随机数，范围是[0，9)，包括0不包括9
        List<Integer> collect = random.ints(0, 9).limit(10).boxed().collect(Collectors.toList());
        collect.forEach(System.out::println);
    }

    // 数组过滤 -》 排序 -》 打印
    private static void testStream01() {
        List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jkl");
        List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
        filtered.forEach(System.out::println);
    }
}
